<?php

namespace Ktnw\LogSupport\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Ktnw\LogSupport\Jobs\SaveUserLogJob;
use Ktnw\LogSupport\Utils\DocParser;
use ReflectionException;
use ReflectionMethod;

class SaveLogMiddleware
{
    /**
     * 注释名称：可自行修改。如修改为:saveUserLog，修改后，controller中请使用 @saveUserLog注释
     */
    const SAVE_LOG = "saveLog";

    /**
     * 正常响应的标识，请自行设置。
     */
    const RESPONSE_SUCCESS_CODE = 1;

    /**
     * Handle an incoming request.
     *
     * @param Request $request
     * @param Closure $next
     * @return mixed
     * @throws ReflectionException
     */
    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);

        $router = $request->route();
        if (!$router) {
            return $response;
        }

        $opInfo = [];
        $action = $router->getActionName();
        $action = explode("@", $action);

        // 反射获取controller的目标方法
        $method = new ReflectionMethod($action[0], $action[1]);
        $docs   = $method->getDocComment();
        $params = DocParser::factory($docs)->getParams();
        if (empty($params) || !in_array(self::SAVE_LOG, array_keys($params))) {
            return $response;
        }

        $param = $params[self::SAVE_LOG];
        $param = explode(",", $param);
        foreach ($param as $item) {
            $item                   = explode(":", $item);
            $opInfo[trim($item[0])] = trim($item[1]);
        }

        if (empty($opInfo["opType"])) {
            return $response;
        }

        $responseData = $response->original;
        $opDesc       = Arr::get($opInfo, "opDesc");
        if ($responseData->code == self::RESPONSE_SUCCESS_CODE) {
            $opResult = "success";
            $opDesc   .= '成功';
        } else {
            $opResult = "fail";
            $opDesc   .= '失败。原因：' . $responseData->message;
        }

        $opParams = $request->all();
        $opUserId = !empty($opParams["user_id"]) ? $opParams["user_id"] : 0;
        $opParams = json_encode($opParams, JSON_UNESCAPED_UNICODE);

        // 创建job并分发到队列
        $logParams = [
            "op_type"     => $opInfo["opType"],
            "op_result"   => $opResult,
            "op_params"   => $opParams,
            "op_user_id"  => $opUserId,
            "op_desc"     => $opDesc,
            "create_time" => date("Y-m-d H:i:s", time()),
        ];
        $job       = new SaveUserLogJob($logParams);
        dispatch($job)->onQueue(env("QUEUE_SAVE_OP_LOG"));


        return $response;
    }

}
